import os
import uuid
import logging
import asyncio
from typing import Optional, Dict, Any, List
from datetime import datetime, timedelta

from sqlalchemy.orm import Session
from sqlalchemy import desc

from apps.meetings.models import Meeting, MeetingStatus
from apps.users.models import User

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(name)s: %(message)s'
)
logger = logging.getLogger(__name__) 


class MeetingService:
    """会议服务类，处理会议相关业务逻辑"""

    def __init__(self, db: Session):
        self.db = db

    def create_meeting(
        self,
        title: str,
        description: str,
        user_id: int,
        file_path: Optional[str] = None,
        file_name: Optional[str] = None
    ) -> Meeting:
        """
        创建新会议
        
        参数:
            title: 会议标题
            description: 会议描述
            user_id: 创建者用户ID
            file_path: 会议文件路径（可选）
            file_name: 会议文件名（可选）
        
        返回:
            创建的会议对象
        """
        try:
            # 创建会议对象
            meeting = Meeting(
                title=title,
                description=description,
                created_by_id=user_id,
                file_path=file_path,
                file_name=file_name,
                status=MeetingStatus.PENDING if file_path else MeetingStatus.COMPLETED,
                created_at=datetime.now(),
                updated_at=datetime.now()
            )

            # 添加到数据库
            self.db.add(meeting)
            self.db.commit()
            self.db.refresh(meeting)

            logger.info(f"用户 {user_id} 创建了新会议: {title} (ID: {meeting.id})")
            return meeting

        except Exception as e:
            self.db.rollback()
            logger.error(f"创建会议失败: {str(e)}")
            raise

    def get_meeting_by_id(self, meeting_id: int) -> Optional[Meeting]:
        """\根据ID获取会议"""
        return self.db.query(Meeting).filter(Meeting.id == meeting_id).first()

    def get_user_meetings(self, user_id: int, limit: int = 100, offset: int = 0) -> List[Meeting]:
        """\获取用户的会议列表"""
        return (
            self.db.query(Meeting)
            .filter(Meeting.created_by_id == user_id)
            .order_by(desc(Meeting.created_at))
            .limit(limit)
            .offset(offset)
            .all()
        )

    def update_meeting(
        self,
        meeting_id: int,
        title: Optional[str] = None,
        description: Optional[str] = None,
        status: Optional[MeetingStatus] = None,
        file_path: Optional[str] = None,
        file_name: Optional[str] = None,
        transcription_result: Optional[Dict[str, Any]] = None
    ) -> Optional[Meeting]:
        """\更新会议信息"""
        meeting = self.get_meeting_by_id(meeting_id)
        
        if not meeting:
            logger.warning(f"会议不存在: {meeting_id}")
            return None

        try:
            # 更新会议信息
            if title is not None:
                meeting.title = title
            if description is not None:
                meeting.description = description
            if status is not None:
                meeting.status = status
            if file_path is not None:
                meeting.file_path = file_path
            if file_name is not None:
                meeting.file_name = file_name
            if transcription_result is not None:
                meeting.transcription_result = transcription_result
                # 如果有转录结果，更新状态为已完成
                if status is None:  # 只有当状态没有被明确设置时才自动更新
                    meeting.status = MeetingStatus.COMPLETED

            meeting.updated_at = datetime.now()

            self.db.commit()
            self.db.refresh(meeting)

            logger.info(f"会议已更新: {meeting_id}")
            return meeting

        except Exception as e:
            self.db.rollback()
            logger.error(f"更新会议失败: {str(e)}")
            raise

    def delete_meeting(self, meeting_id: int) -> bool:
        """删除会议"""
        meeting = self.get_meeting_by_id(meeting_id)
        
        if not meeting:
            logger.warning(f"会议不存在: {meeting_id}")
            return False

        try:
            self.db.delete(meeting)
            self.db.commit()
            logger.info(f"会议已删除: {meeting_id}")
            return True

        except Exception as e:
            self.db.rollback()
            logger.error(f"删除会议失败: {str(e)}")
            raise

    def update_meeting_status(self, meeting_id: int, status: MeetingStatus) -> Optional[Meeting]:
        """更新会议状态"""
        return self.update_meeting(meeting_id, status=status)

    def set_meeting_transcription_result(
        self, meeting_id: int, transcription_result: Dict[str, Any]
    ) -> Optional[Meeting]:
        """设置会议转录结果"""
        return self.update_meeting(
            meeting_id,
            transcription_result=transcription_result,
            status=MeetingStatus.COMPLETED
        )

    def process_meeting_audio(
        self, meeting_id: int, audio_path: str
    ) -> Dict[str, Any]:
        """
        处理会议音频文件（同步版本）
        这里是一个占位方法，实际应用中会调用ASR服务进行转录
        """
        try:
            # 更新会议状态为处理中
            self.update_meeting_status(meeting_id, MeetingStatus.PROCESSING)
            
            # 模拟音频处理延迟
            logger.info(f"开始处理会议音频: {meeting_id}")
            import time
            time.sleep(2)  # 模拟处理时间
            
            # 模拟转录结果
            mock_transcription = {
                "text": "这是一段模拟的会议录音转录结果。会议讨论了项目的进展情况。",
                "segments": [
                    {
                        "text": "这是一段模拟的会议录音转录结果。",
                        "start_time": 0.0,
                        "end_time": 5.0,
                        "speaker_id": "speaker_1"
                    },
                    {
                        "text": "会议讨论了项目的进展情况。",
                        "start_time": 5.5,
                        "end_time": 9.0,
                        "speaker_id": "speaker_2"
                    }
                ],
                "audio_duration": 9.0,
                "processing_time": 2.0
            }
            
            # 更新会议转录结果
            self.set_meeting_transcription_result(meeting_id, mock_transcription)
            
            logger.info(f"会议音频处理完成: {meeting_id}")
            return mock_transcription
            
        except Exception as e:
            # 出错时更新状态为失败
            self.update_meeting_status(meeting_id, MeetingStatus.FAILED)
            logger.error(f"处理会议音频失败: {str(e)}")
            raise

    async def process_meeting_audio_async(
        self, meeting_id: int, audio_path: str
    ) -> Dict[str, Any]:
        """\异步处理会议音频文件"""
        # 在异步环境中运行同步处理函数
        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(
            None,  # 使用默认执行器
            self.process_meeting_audio, 
            meeting_id, 
            audio_path
        )
        return result

    def get_meeting_statistics(self, user_id: int) -> Dict[str, int]:
        """获取用户的会议统计信息"""
        total_meetings = self.db.query(Meeting).filter(Meeting.created_by_id == user_id).count()
        completed_meetings = self.db.query(Meeting).filter(
            Meeting.created_by_id == user_id,
            Meeting.status == MeetingStatus.COMPLETED
        ).count()
        processing_meetings = self.db.query(Meeting).filter(
            Meeting.created_by_id == user_id,
            Meeting.status == MeetingStatus.PROCESSING
        ).count()
        failed_meetings = self.db.query(Meeting).filter(
            Meeting.created_by_id == user_id,
            Meeting.status == MeetingStatus.FAILED
        ).count()
        
        return {
            "total": total_meetings,
            "completed": completed_meetings,
            "processing": processing_meetings,
            "failed": failed_meetings
        }


# 工厂函数，用于在依赖注入中获取MeetingService实例
def get_meeting_service(db: Session) -> MeetingService:
    """获取会议服务实例"""
    return MeetingService(db)